<!doctype html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
// Unhandled rejections must be permitted due to the expected unhandled
// reections described below.
setup({
  allow_uncaught_exception: true
});
// Running put several times is necessary to trigger the crash, but running too
// many times causes the test to timeout on windows.
let putRunsLeft = 64;
// fillStackAndRun() doesn't not cause a stack overflow in this test. This is
// probably because put() takes two arguments.
function fillStackThenCallPut(foo, request, response) {
    try {
        fillStackThenCallPut(foo, request, response);
    } finally {
        // This runs thousands of times, causing the console to spew "Uncaught
        // (in promise) TypeError: Response body is already used" messages, but
        // it's harmless. The rejection cannot be handled because the call
        // stack is full.
        if (putRunsLeft > 0) {
          --putRunsLeft;
          foo.put(request, response);
        }
    }
}

promise_test(async t => {
    const request = new Request('/');
    const response = new Response('foo');
    const foo = await caches.open('foo');
    t.add_cleanup(() => caches.delete('foo'));
    await foo.put(request, response);
    assert_throws_js(
        RangeError, () => fillStackThenCallPut(foo, request, response),
        'fillStackThenCallPut should throw');
}, 'stack overflow in IsLocked() should not crash the browser');
</script>
